//  
//  Copyright (C) 2004-2009  Autodesk, Inc.
//  
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of version 2.1 of the GNU Lesser
//  General Public License as published by the Free Software Foundation.
//  
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//  
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
//  
#ifndef MAPINFOCONNECTION_H
#define MAPINFOCONNECTION_H

#include <FdoCommonThreadMutex.h>

//forward declare
class MapInfoConnectionInfo;
class MapInfoFeatureSchemaCollection;
class MapInfoClassDefinition;
class MapInfoSpatialContext;
class MapInfoSpatialContextCollection;

class MapInfoConnection : public FdoIConnection
{
    //-------------------------------------------------------
    // Constructor / destructor
    //-------------------------------------------------------
public:
    MAPINFO_API MapInfoConnection();

protected:
    MAPINFO_API ~MapInfoConnection();

public:
    MAPINFO_API static MapInfoConnection* Create();

    //-------------------------------------------------------
    // FdoIDisposable implementation
    //-------------------------------------------------------

protected:
    // dispose this object
    MAPINFO_API virtual void Dispose();

    //-------------------------------------------------------
    // FdoIConnection implementation
    //-------------------------------------------------------

public:
    // Returns an IConnectionCapabilities interface describing the
    // capabilities of the connection.
    MAPINFO_API virtual FdoIConnectionCapabilities* GetConnectionCapabilities();

    // Returns an ISchemaCapabilities interface describing the
    // provider's support for the feature schema.
    MAPINFO_API virtual FdoISchemaCapabilities* GetSchemaCapabilities();

    // Returns an ICommandCapabilities interface describing the
    // commands a provider supports.
    MAPINFO_API virtual FdoICommandCapabilities* GetCommandCapabilities();

    // Returns an IFilterCapabilities interface describing the
    // provider's support for filters.
    MAPINFO_API virtual FdoIFilterCapabilities* GetFilterCapabilities();

    // Returns an IExpressionCapabilities interface describing the
    // provider's support for expressions.
    MAPINFO_API virtual FdoIExpressionCapabilities* GetExpressionCapabilities();

    /// <summary>Gets an FdoIRasterCapabilities interface describing the provider's support for raster images.</summary>
    /// <returns>Returns the raster capabilities</returns> 
    MAPINFO_API virtual FdoIRasterCapabilities* GetRasterCapabilities();

    /// <summary>Gets an FdoITopologyCapabilities interface describing the provider's support for topology.</summary>
    /// <returns>Returns the topology capabilities</returns> 
    MAPINFO_API virtual FdoITopologyCapabilities* GetTopologyCapabilities();

    /// <summary>Gets an FdoIGeometryCapabilities interface describing the provider's support for geometry.</summary>
    /// <returns>Returns the geometry capabilities</returns> 
    virtual FdoIGeometryCapabilities* GetGeometryCapabilities();
 
    // Gets the connection string used to open a data store.
    MAPINFO_API virtual FdoString* GetConnectionString();

    // Sets the connection string used to open a data store.  Can
    // only be set while the connection is closed.
    MAPINFO_API virtual void SetConnectionString(FdoString* value);

    // Returns an IConnectionInfo interface that can be used to
    // interrogate and set connection properties.
    MAPINFO_API virtual FdoIConnectionInfo* GetConnectionInfo();

    // Gets the current state of the connection.
    MAPINFO_API virtual FdoConnectionState GetConnectionState();

    // Gets the number of milliseconds to wait while trying to establish a
    // connection before terminating the attempt and generating an error.  If
    // the provider does not support the timeout capability 0 will be returned.
    MAPINFO_API virtual FdoInt32 GetConnectionTimeout();

    // Sets the number of milliseconds to wait while trying to establish a
    // connection before terminating the attempt and generating an error.  If
    // the provider does not support the timeout capability then attempting
    // to set a timeout will result in an exception.
    MAPINFO_API virtual void SetConnectionTimeout(FdoInt32 value);

    // Opens a feature connection with the settings specified by the
    // ConnectionString attribute of the provider-specific feature connection
    // object.
    MAPINFO_API virtual FdoConnectionState Open();

    // Closes the connection to the data store.
    MAPINFO_API virtual void Close();

    // Begins a transaction and returns an ITransaction object.
    MAPINFO_API virtual FdoITransaction* BeginTransaction();

    // Creates and returns the specified type of command object
    // associated with the connection.
    MAPINFO_API virtual FdoICommand* CreateCommand(FdoInt32 commandType);

    /// <summary>Factory function that creates an empty Schema Override set specific
    /// to this FDO Provider.</summary>
    /// <returns>Returns FdoPhysicalSchemaMapping</returns> 
    MAPINFO_API virtual FdoPhysicalSchemaMapping* CreateSchemaMapping();

    MAPINFO_API virtual void SetConfiguration(FdoIoStream* stream);

    MAPINFO_API virtual void Flush();

public:
    void ReOpen();
    MapInfoSpatialContext* GetSpatialContext(FdoString* scName);
    MapInfoSpatialContextCollection* GetSpatialContexts(bool bForce = false);
    FdoFeatureSchemaCollection* GetFdoSchemas();
    MapInfoFeatureSchemaCollection* GetMapInfoSchemas();
    MapInfoClassDefinition* GetMapInfoClassDefinition(FdoClassDefinition* classDef);
    MapInfoClassDefinition* GetMapInfoClassDefinition(FdoString* className);
    FdoFeatureSchemaCollection* DescribeSchema(bool bForce = false);
    FdoIFeatureReader* Select(FdoIdentifier* fcname, FdoFilter* filter, FdoIdentifierCollection* props);
    FdoIFeatureReader* Insert(FdoIdentifier* fcname, FdoPropertyValueCollection* propvals);
    FdoIFeatureReader* Insert(FdoIdentifier* fcname, FdoBatchParameterValueCollection* batchPropVals, FdoPropertyValueCollection* propvals);
    FdoInt32 Delete(FdoIdentifier* fcname, FdoFilter* filter);
    FdoInt32 Update(FdoIdentifier* fcname, FdoFilter* filter, FdoPropertyValueCollection* propvals);
    OGRTABDataSource* GetOGRDataSource() { return m_poDS; }
    void CreateSpatialContext(  FdoString* name,
                                FdoString* description,
                                FdoString* csName,
                                FdoString* wkt,
                                FdoSpatialContextExtentType extentType,
                                FdoByteArray * extent,
                                double xyTolerance,
                                double zTolerance);
    FdoString* GetDirectory ();
    FdoString* GetFile ();
    FdoStringP GetFileDirectory ();
    bool IsConnectToFolder ();
    bool IsConnectToFile ();

protected:
    void InitConnectionPaths();
    MapInfoClassDefinition* ValidateClassForModification(FdoString* className);

protected:
    /**
     * The connection string containing details about how to connect to MapInfo.
     */
    FdoStringP m_connectionString;

private:
    FdoConnectionState m_connState;
    MapInfoConnectionInfo* m_connInfo;
    FdoFeatureSchemaCollection* m_pFdoSchemas;
    MapInfoFeatureSchemaCollection* m_pMapInfoSchemas;
    MapInfoSpatialContextCollection* m_pSpatialContextColl;
    OGRTABDataSource* m_poDS;
};

#endif
